{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "e3f1b229",
   "metadata": {},
   "source": [
    "------\n",
    "* 记录人：李柏慧\n",
    "* 时间：2021-11-29\n",
    "* week14\n",
    "* 主要参考文档:\n",
    "> 1.[Python官方文档](https://www.python.org/doc/)\n",
    "> 2.[博客——函数](https://www.cnblogs.com/xuzhichao/p/11570285.html)\n",
    "\n",
    "------"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f912bf2c",
   "metadata": {},
   "source": [
    "# 本周内容\n",
    "1、函数的定义\n",
    "\n",
    "2、如何使用函数\n",
    "\n",
    "3、函数的返回值\n",
    "\n",
    "4、使用注释改进文档\n",
    "\n",
    "5、传递任意数量的实参\n",
    "\n",
    "6、函数与模块"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b661042f",
   "metadata": {},
   "source": [
    "## 1.函数的定义\n",
    "> 1. 写def: def 定义函数的第一步\n",
    "> 2. 写定义函数的名称： def function_name \n",
    ">> 1.function_name 遵循变量名称定义的规则\n",
    "> 3.函数名称后加上“（）：”  def function_name()： ===> f(x) = 2x\n",
    "\n",
    "* 书写函数体\n",
    "> 1.函数的注释\n",
    "> 2.写函数的具体操作（函数体）\n",
    "> 3.注意： 函数也是需要有tab键的间距\n",
    "\n",
    "* 使用函数(函数的调用)\n",
    "> 1.function_name()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6c9501fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):    # write Fibonacci series up to n\n",
    "     \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "     a, b = 0, 1\n",
    "     while a < n:\n",
    "         print(a, end=' ')\n",
    "         a, b = b, a+b\n",
    "     print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "6d42b706",
   "metadata": {},
   "outputs": [],
   "source": [
    "# def:定义(define)函数的关键字\n",
    "# fib：函数名\n",
    "# (n)：定义函数的参数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "eb3e7bdb",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 \n"
     ]
    }
   ],
   "source": [
    "fib(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "d27d6bb7",
   "metadata": {},
   "outputs": [],
   "source": [
    "## 尝试： 写一个实现hello world 的函数\n",
    "def hello():\n",
    "    print(\"Hello world!\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "fb14d3ef",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world!\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "77934dfe",
   "metadata": {},
   "source": [
    "## 如何使用函数（课本实践p149）"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "55269365",
   "metadata": {},
   "source": [
    "## 思考函数存在的意义？\n",
    "### 1.可以通过调用函数的方式实现某些功能，使用人不需要考虑函数代码内容\n",
    "### 2.节省时间，提升应用的效率\n",
    "### 3.函数一旦定义，就可按照一定的规则重复使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "6576c82e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义了一个名字叫“search4vowels” 函数\n",
    "def search4vowels(word):\n",
    "    \"\"\"\n",
    "    打印文本中出现的元音字母\n",
    "    请输入你需要查询的文本内容\n",
    "    \"\"\"\n",
    "    vowels = set('aeiou')\n",
    "    found = vowels.intersection(set(word))  # 交集运算\n",
    "    print(found)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "7b4013e2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on function search4vowels in module __main__:\n",
      "\n",
      "search4vowels(word)\n",
      "    打印文本中出现的元音字母\n",
      "    请输入你需要查询的文本内容\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(search4vowels)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "903a8245",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'a', 'i'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"absidjr\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "eb8dc834",
   "metadata": {},
   "source": [
    "------\n",
    "* 下面的方法是不是太重复了，主要原因是没有对重复功能的代码块有特殊的定义（如:名称，注释）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "7a23b283",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Provide a word to search for vowels:backpink\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'a', 'i'}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowels = set('aeiou')\n",
    "word = input(\"Provide a word to search for vowels:\")\n",
    "found = vowels.intersection(set(word))\n",
    "found"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "3a06aea0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Provide a word to search for vowels:hojjijiera\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{'a', 'e', 'i', 'o'}"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "vowels = set('aeiou')\n",
    "word = input(\"Provide a word to search for vowels:\")\n",
    "found = vowels.intersection(set(word))\n",
    "found"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "4410fcbb",
   "metadata": {},
   "source": [
    "# 3.函数的参数\n",
    "\n",
    "* <font style=\"color:red\"> 注意：函数的参数可以没有,如果有函数，则如下（分为形式参数和实际参数）：</font>\n",
    "> 1.形式参数（形参）\n",
    ">> 1.在定义过程中，函数的参数为形式参数\n",
    ">> 2.形式参数是虚拟的，不占用空间的\n",
    "\n",
    "> 2.实际参数（实参）\n",
    ">> 1.调用函数过程中，函数的参数为实际参数\n",
    ">> 2.调用函数时，形式参数被分配空间，成为实际参数并应用起来"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "2ae993ee",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello world!\n"
     ]
    }
   ],
   "source": [
    "# 函数式可以没有函数\n",
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "d861b974",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 定义函数\n",
    "def greet_user(username):\n",
    "    \"\"\"显示简单的问候语，输入你的名字\"\"\"\n",
    "    print(\"hello,\"+ username.title()+\"!\")\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "c9565915",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,Bohui!\n"
     ]
    }
   ],
   "source": [
    "# 调用函数\n",
    "# username = \"bohui\"\n",
    "greet_user(\"bohui\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c166f2e6",
   "metadata": {},
   "source": [
    "* 当参数不止一个时：\n",
    "> 1.位置参数（positional argument）\n",
    ">> 2.形式参数有多个值，如果实际参数直接赋值，要按照形式参数的先后顺序，这种方式称：位置参数赋值\n",
    "\n",
    ">> 2.在调用函数过程中需要考虑如下：\n",
    ">>> 1.考虑位置\n",
    ">>> 2.考虑个数\n",
    "\n",
    "> 2.关键字参数\n",
    ">> 1.在调用函数时使用，我们直接在实参中，用赋值的方式定义形参\n",
    "\n",
    ">>2.不需要考虑顺序，因为赋值已经确定了形式参数的值\n",
    "\n",
    ">3.默认参数\n",
    ">> 1.默认参数写在形式参数中(预计有大量的调用会使用到的值，可以预先设置)\n",
    "\n",
    ">> 2.默认参数存在的话，实际调用过程中可以省略赋值的过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "a9f7d8c9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 请注意，有两个参数\n",
    "def describe_pet(animal_type,pet_name):\n",
    "    \"\"\"显示宠物信息,animal_type 的默认值'dog'\"\"\"\n",
    "    print(\"\\nI have a \" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "765e1946",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\",\"豆豆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "c293be5b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数\n",
    "describe_pet(animal_type=\"dog\",pet_name=\"豆豆\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "8331aac7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(pet_name=\"豆豆\",animal_type=\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "id": "29d1d835",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 默认参数(写在形式参数中的)\n",
    "\n",
    "def describe_pet(pet_name,animal_type=\"dog\"):\n",
    "    \"\"\"显示宠物信息,animal_type 的默认值 'dog'\"\"\"\n",
    "    print(\"\\nI have a \" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "f3ec8206",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a dog.\n",
      "My dog's name is 豆豆.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"豆豆\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "20905881",
   "metadata": {},
   "source": [
    "* 实操和注意（参数部分）\n",
    ">1.如果想 关键字参数 和 位置参数共同使用\n",
    ">> 1.positional argument follows keyword argument(位置参数需要放在关键字参数的前面)\n",
    ">> 2.关键字参数放在末尾（全是关键字，不考虑顺序）\n",
    "\n",
    "\n",
    "> 2.默认参数\n",
    ">> 1.non-default argument follows default argument（非默认参数需要放在默认参数前面）\n",
    ">>2.默认参数放在末尾（全是默认参数，不考虑顺序）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "id": "0301267f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg1\n",
    "def func_test(x,y):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    \n",
    "func_test(2,y=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "af743b40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "1\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg2\n",
    "def func_test(x,y,z):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,1,z=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "id": "bce47fb1",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "5\n",
      "3\n"
     ]
    }
   ],
   "source": [
    "#eg3\n",
    "def func_test(x,z,y=3):\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)\n",
    "    \n",
    "func_test(2,3,5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aa1ea26f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
